﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace Lab1
{
    class Face
    {
        private List<CustomVertex.PositionNormalTextured> vertices = new List<CustomVertex.PositionNormalTextured>();
        public int numberOfTriangles { set; get; }

        public CustomVertex.PositionNormalTextured[] getVertices()
        {
            numberOfTriangles = vertices.Count/3;
            return vertices.ToArray();
        }

        internal void AddVertex(Vector3 position, Vector3 normal, float Tu, float Tv)
        {
            CustomVertex.PositionNormalTextured v = new CustomVertex.PositionNormalTextured();
            v.Position = position;
            v.Normal = normal;
            v.Tu = Tu;
            v.Tv = Tv;
            vertices.Add(v);
        }

        internal Face TranslateX(float p)
        {
            Face newFace = new Face();
            foreach(CustomVertex.PositionNormalTextured v in vertices){
                Vector3 newV = new Vector3(v.Position.X + p, v.Position.Y, v.Position.Z);
                newFace.AddVertex(newV, v.Normal, v.Tu, v.Tv);
            }
            return newFace;
        }

        internal Face TranslateY(float p)
        {
            Face newFace = new Face();
            foreach (CustomVertex.PositionNormalTextured v in vertices)
            {
                Vector3 newV = new Vector3(v.Position.X, v.Position.Y + p, v.Position.Z);
                newFace.AddVertex(newV, v.Normal, v.Tu, v.Tv);
            }
            return newFace;
        }

        internal Face TranslateZ(float p)
        {
            Face newFace = new Face();
            foreach (CustomVertex.PositionNormalTextured v in vertices)
            {
                Vector3 newV = new Vector3(v.Position.X, v.Position.Y, v.Position.Z + p);
                newFace.AddVertex(newV, v.Normal, v.Tu, v.Tv);
            }
            return newFace;
        }

        internal Face RotateX(double p)
        {
            double angle = Math.PI * p / 180.0;
            Face newFace = new Face();
            foreach (CustomVertex.PositionNormalTextured v in vertices)
            {
                Vector3 newV = new Vector3();
                newV.X = v.Position.X;
                newV.Y = (float)(v.Position.Y * Math.Cos(angle) - v.Position.Z * Math.Sin(angle));
                newV.Z = (float)(v.Position.Y * Math.Sin(angle) + v.Position.Z * Math.Cos(angle));
                newFace.AddVertex(newV, v.Normal, v.Tu, v.Tv);
            }
            return newFace;
        }

        internal Face RotateY(double p)
        {
            double angle = Math.PI * p / 180.0;
            Face newFace = new Face();
            foreach (CustomVertex.PositionNormalTextured v in vertices)
            {
                Vector3 newV = new Vector3();
                newV.X = (float)(v.Position.X * Math.Cos(angle) + v.Position.Z * Math.Sin(angle));
                newV.Y = v.Position.Y;
                newV.Z = (float)(-v.Position.X * Math.Sin(angle) + v.Position.Z * Math.Cos(angle));
                newFace.AddVertex(newV, v.Normal, v.Tu, v.Tv);
            }
            return newFace;
        }

        internal Face RotateZ(double p)
        {
            double angle = Math.PI * p / 180.0;
            Face newFace = new Face();
            foreach (CustomVertex.PositionNormalTextured v in vertices)
            {
                Vector3 newV = new Vector3();
                newV.X = (float)(v.Position.X * Math.Cos(angle) - v.Position.Y * Math.Sin(angle));
                newV.Y = v.Position.Y;
                newV.Z = (float)(v.Position.X * Math.Sin(angle) + v.Position.Y * Math.Cos(angle));
                newFace.AddVertex(newV, v.Normal, v.Tu, v.Tv);
            }
            return newFace;
        }

        internal void UpdateNormal(Vector3 normal)
        {
            List<CustomVertex.PositionNormalTextured> updated = new List<CustomVertex.PositionNormalTextured>();
            foreach(CustomVertex.PositionNormalTextured pnt in vertices)
            {
                CustomVertex.PositionNormalTextured newPnt = new CustomVertex.PositionNormalTextured(pnt.Position, normal, pnt.Tu,pnt.Tv);
                updated.Add(newPnt);
            }
            vertices = updated;
        }

        internal void adjustHeight(float c)
        {
            float highestZ = -c;
            foreach (CustomVertex.PositionNormalTextured pnt in vertices)
            {
                if (pnt.Z > highestZ)
                {
                    highestZ = pnt.Z;
                }
            }

            float newZ = c / 2.0F;
            for(int i = 0; i < vertices.Count; i++)
            {
                if (vertices[i].Z == highestZ)
                {
                    CustomVertex.PositionNormalTextured pnt = vertices[i];
                    pnt.Z = newZ;
                    vertices[i] = pnt;
                }
            }
        }
    }
}
